﻿using System;
using System.Reflection;
using System.ServiceModel;
using System.ServiceModel.Channels;
using LinFu.AOP.Interfaces;
using CoreEx.DynamicInvoker;


namespace CoreEx.Wcf.Common.Implementation
{
    public class DefaultServiceContractInterceptor : IInvokeWrapper
    {
        private object _actualTarget;
        private IChannelFactory _channelFactory;
        
        public DefaultServiceContractInterceptor(object channelFactory)
        {
            _channelFactory = (IChannelFactory)channelFactory;            
        }


      
        public void BeforeInvoke(IInvocationInfo info)
        {
            _actualTarget = _channelFactory.GetType().InvokeMember("CreateChannel",
                                                                     BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod, null,
                                                                     _channelFactory, null);                                                                                                                                                                                                       
        }

        public void AfterInvoke(IInvocationInfo info, object returnValue)
        {
            var channel = (IChannel) _actualTarget;
            try
            {
                channel.Close();
            }
            catch (Exception)
            {                
                channel.Abort();
            }
        }

        public object DoInvoke(IInvocationInfo info)
        {
            return _actualTarget.GetType().DynamicInvoke(_actualTarget, info.TargetMethod.Name, info.Arguments); 
        }
    }
}